现在大家流行用静态博客,还没有接触Emacs之前,我是打算使用Markdown写作的,认识Org Mode这个强大的工具之后,我就开始想方设法改用Org Mode,特别是org-mode的babel可以直接执行文章中的代码块并把结果显示在代码块后,我想这就是所谓的文学编程吧,经过一番努力之后,终于驾驭Org Mode写博客了。在看了子龙山人的博客之后,开始用org-octopress写博客,但是这个包并不支持管理Markdown格式的博客,只能用来管理org格式的文章,markdown格式的文章需要自己管理。后来发现Codefalling写了2个包,一个是blog—admin,它同时能够兼容org、markdown和org-page,另外一个包是hexo-render-org,它让hexo支持渲染org格式的文章,到目前为止,终于驯服了Emacs用来写博客。

Codefalling同学还有写了另外一个包hexo-asset-image,用于使hexo支持本地图片,就不需要图床了,而且这个插件同时支持markdown和org,真是应该给他点个赞。我fork了这个包为了支持file协议打了个小补丁,觉得这可能只有我有这个需求。如果你也需要的话,欢迎下载https://github.com/wing-ho/hexo-asset-image

默认设置下org-mode下的图片连接是会直接显示图片的,这会给编辑文章带来一些不便,可以通过快捷键,Ti来开关图片显示功能。

我使用的Emacs配置文件是建立在Spacemacs之上的,熟悉了Spacemacs配置方式,会非常喜欢它用层来隔离不同的配置的方式。如果你有同样的需求,可以参考我的layer。

cd ~/.emacs.d
git clone https://github.com/wing-ho/spacemacs-private.git
mv spacemacs-private/wing private/
#https://sourceforge.net/projects/plantuml/files/plantuml.jar/download
#下载plantuml.jar放到private文件夹中
sudo apt-get install graphviz

图1  博客管理界面

1 在正文中执行代码并输出结果

将光标落在代码标签内,按C-c C-c y就可以直接执行代码并输出结果。 :exports选项是控制导出成html或者其他格式时的内容。

  • code 导出代码
  • results 导出执行结果
  • both 导出代码和结果
  • none 不导出任何内容

图2  代码直接执行的结果

下面是同时导出代码和执行结果的效果。

df
Filesystem 1K-blocks Used Available Use% Mounted on
dev 4025804 0 4025804 0% /dev  
run 4030776 1280 4029496 1% /run  
/dev/nvme0n1p6 315518128 41378444 258042560 14% /  
tmpfs 4030776 0 4030776 0% /dev/shm  
tmpfs 4030776 0 4030776 0% /sys/fs/cgroup  
tmpfs 4030776 16 4030760 1% /tmp  
/dev/nvme0n1p1 98304 25866 72438 27% /boot/EFI  
tmpfs 806152 12 806140 1% /run/user/1000  

2 主题

我比较喜欢简单的灰色系主题Maupassant,但是它跟多数的hexo主题一样只支持Mardown格式的博客,org-mode写的博客,目录样式是没有定义的,图片或者表格的标题不居中,该主题作者应该不用org-mode,我打了个补丁自用,需要的话,欢迎下载https://github.com/wing-ho/hexo-filter-maupassant。另外原主题取第一个段落的逻辑有一点问题,我也做了修改https://github.com/wing-ho/maupassant-hexo.git

3 关于hexo-renderer-org的坑

3.1 org-version版本较低导致导出有问题

花了几个小时调试hexo-render-org才找到原因,估计是org-mode的版本和编译org-plus-contrib包的版本不一致导致的,可能是安装spacemacs的时候时候用系统自带的org 8.2编译org-plus-contrib。版本不一致还导致了在org-mode下code block没有办法按C-c C-c执行。这个bug是比较隐秘的,通常只发生在第一次安装spacemacs的时候,使用过程中org-mode的package升级过之后就不会有这个副作用了。 解决方法:M-x package-reinstall,重新安装org和org-plus-contrib包,M-x org-version检查org-mode的版本是否与生成的html文件一致。

3.2 后续的维护者hexo-renderer-org改变了原有程序逻辑导致的故障

出现这个故障是因为我需要用到plantuml来画UML图,file参数是生成的文件路径,我用到了函数buffer-file-name,CodeFalling的处理逻辑是在源文件导出html后再处理,这时候buffer-file-name函数的返回值是有效的,Coldnew的处理逻辑是放到一个把原文件复制到temp buffer中再添加额外的控制信息,再导出html,这样的做法会导致buffer-file-name这样的函数返回nil。更新hexo-renderer-org之后,我有几篇有后置处理的博客就挂掉了,又花了半天时间去调试代码才搞清楚程序执行的流程,新的hexo-renderer-org也有值得表扬的地方,就是把图片拖放的功能做出来,以后写博客就简单很多了。

4 图片拖放功能

我是从hexo-renderer-org包的介绍中了解到可以在博客的根目录中添加.dir-locals.el文件来添加拖放的功能,这是通过调用org-download这个包中的方法来实现的。我以为可以简单地在该文件中增加相应的代码就能够在markdown-mode生成正确的图片标记,一番研究研究下来,发现没有那么简单,搜索过程中还找到了markdown-dnd-images这个包,想着凑合着用就好了,打开源代码看了一下,实现拖放的逻辑与org-download十分相似,觉得可以只用org-download就可以完成两种文档的拖放功能,于是认真地阅读了一下org-download的源代码。hack了几个函数,就把markdown-mode下的拖放做好了,不再需要每次打开文档都提示加载的.dir-locals.el。

(defun dotspacemacs/user-config ()
(with-eval-after-load 'org-download
(defun org-download-annotate-default (link)
"Annotate LINK with the time of download."
(format "#+DOWNLOADED: %s @ %s"
(org-link-unescape link)
(format-time-string "%Y-%m-%d %H:%M:%S")))

(defun org-download-dnd (uri action)
"When in `org-mode' and URI points to image, download it.
Otherwise, pass URI and ACTION back to dnd dispatch."

(cond ((eq major-mode 'org-mode)
(condition-case nil
(org-download-image uri)
(error
(org-download-dnd-fallback uri action)))
)

;;添加markdown-mode的判断逻辑
((eq major-mode 'markdown-mode)
(condition-case nil
(org-download-image uri)
(error
(org-download-dnd-fallback uri action)))
)

((eq major-mode 'dired-mode)
(org-download-dired uri))

;; redirect to someone else
(t
(org-download-dnd-fallback uri action)))
)

;;https://github.com/coldnew/hexo-renderer-org/#can-i-drag-and-drop-image-to-org-files-
(defun my-org-download-method (link)
(let ((filename
(file-name-nondirectory
(car (url-path-and-query
(url-generic-parse-url (org-link-unescape link))))
)
)

(dirname (file-name-sans-extension (buffer-name)) ))

;; if directory not exist, create it
(unless (file-exists-p dirname)
(make-directory dirname))

;; return the path to save the download files
(expand-file-name filename dirname))

)

(setq org-download-method 'my-org-download-method)
)

(add-hook 'markdown-mode-hook (lambda()
(setq-local org-download-link-format "![](%s)")
(org-download-enable)
))

)

5 评论系统

博客的评论少得可怜,会不会估计跟disqus被墙有关系啊!看到有人给自己的博客的评论系统disqus做了个代理,试了一下,果然可用,包名叫hexo-disqus-proxy,暂时这样用着吧,有种自己写一个评论系统的冲动了。

6 SEO优化

写独立博客当然希望能被更多的人看到,但前提是被搜索引擎收录,可是百度爬虫被Github屏蔽了,有什么方法可以让百度可以索引自己的博客呢?答案就是同时部署在coding和github上,然后通过dnspod进行多线路解析。

6.1 双线域名解析设置

设置的过程中,踩了一些坑,希望你比我幸运:

1.域名DNS服务器设置不能混用多个不同的 Name Server,像下面这种情况会导致解析出错的。

图3  错误混用多个Namer Server

2.多人提到添加www的CNAME解析,解析记录值为pages.coding.me,经测试这条记录是无效的,官方文档上说:“绑定前请在域名 DNS 设置中添加一条 CNAME 记录指向 xxxx.coding.me。将@和www记录都解析到这个即可。”实际上这样设置@主机记录能够正确解析,但是Coding Pages却不能绑定到主域名callmewing.com,绑定的时候提示“域名未连通”。只能绑定到子域名www.callmewing.com。为了可以直接通过主域名callmewing.com访问博客,可以将@主机记录配置成A类型记录指向云主机IP地址,在云主机上通过Nginx配置301重定向到www.callmewing.com。

图4  设置DNSPod的正确方法

在Nginx配置文件的中添加以下配置:

server {
listen 80;
server_name callmewing.com;
return 301 $scheme://www.callmewing.com$request_uri;
}

6.2 设置强制 HTTPS 访问

Coding直接设置强制 HTTPS 访问就可以了。但是 Github 之前已经开启了自定义域名, enforce HTTPS 无法勾选。

图5  Github enforce HTTPS 无法勾选

解决方法按照官方提示,进行如下操作:

  1. 把 Custom domain 中的值清空,并点击 Save 进行保存;
  2. 在 Custom domain 中的填入之前清空的值,我这里是 likfe.com ,填入后点击保存;
  3. 尝试在浏览器里主动访问 https://callmewing.com ,地址要根据自己的情况,注意协议类型是 https,正确情况下是能正常访问的;
  4. 刷新项目设置页,如果 enforce HTTPS 可勾选,勾选即可;
  5. 如果 enforce HTTPS 不可勾选,并且提示 Not yet available for your site because the certificate has not finished being issued” ,说明证书尚未申请完成,等待一天即可。
Last Updated 2018-10-14 日 23:38.
Created by Emacs 25.1.1 (Org mode 9.1.14)